package com.humngyang.com.hmy.study.concurrency.myannoations.pushObject;

import com.humngyang.com.hmy.study.concurrency.myannoations.ThreadUnSafe;
import com.humngyang.com.hmy.study.concurrency.myannoations.UnRecommend;


//单例模式只懒汉模式双重同步锁单例模式
@ThreadUnSafe
@UnRecommend
public class SingletonExample3 {
    //构造方法私有化,不允许外面的方法直接调用
    private SingletonExample3(){}
    //定义一个单例对象
    private static SingletonExample3 instance = null;
    /*
     * 为什么双重同步锁机制不是线程安全的，因为当我们实例化一个对象的时候要进行三步操作
     *      1：分配对象的内存空间
     *      2：初始化对象
     *      3：设置instance指向刚设置的内存
     * 因为在多线程的时候，JVM和CPU优化会产生指令重排如下所示，
     *      1：分配对象的内存空间
     *      3：设置instance指向刚设置的内存
     *      2：初始化对象
     *
     *      当A到了32行的时候，B走到29行的时候，会导致B判断时发现已经实例了，但是事实上A还没有进行初始化对象，导致B拿到的对象为空，产生问题。
     */
    //双重检测机制
    private static synchronized SingletonExample3 getInstance(){
        if (instance == null){                           //B
            synchronized (SingletonExample3.class){//同步锁
                if (instance == null){
                    instance = new SingletonExample3();  //A
                }
            }
        }
        return instance;
    }
}
